/*
 *  Copyright (C) void Team 2010 Pedro Batista
 * 
 *  http://code.google.com/p/capacitec
 * 
 *  This file is part of capacitec.
 * 
 *  capacitec is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  capacitec is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with capacitec.  If not, see <http://www.gnu.org/licenses/>.
 */
package dao;

import br.com.caelum.vraptor.ioc.Component;
import entidades.Pessoa;
import java.util.List;
import org.hibernate.PropertyValueException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * Responsável por fazer operações no banco de dados envolvendo a classe Pessoa.
 * @author Pedro Batista
 */
@Component
public class PessoaDao {

	private final Session session;

	/**
	 * Instancia uma nova PessoaDao.
	 * @param session Sessão do hibernate para acessar o banco de dados.
	 */
	public PessoaDao(Session session) {
		this.session = session;
	}

	/**
	 * Adiciona uma nova pessoa ao banco de dados.
	 *
	 * O login será sobrescrito com o cpf da pessoa.
	 * @param pessoa Pessoa a ser adicionado no banco de dados.
	 * @throws PropertyValueException Caso o cpf em Pessoa já esteja
	 * cadastrado ou haja outro erro na trasição com o banco.
	 */
	public void salva(Pessoa pessoa) throws PropertyValueException {
		Transaction tx = session.beginTransaction();

		pessoa.setLogin(pessoa.getCpf());

		try {
			session.save(pessoa);
		} catch (PropertyValueException ex) {
			throw ex;
		}
		tx.commit();
	}

	/**
	 * Busca no banco de dados a pessoa com o id e a retorna.
	 * @param id Id da pessoa a ser buscado.
	 * @return Pessoa encontrado.
	 */
	public Pessoa carrega(Integer id) {
		Pessoa pessoa;
		pessoa = (Pessoa) session.load(Pessoa.class, id);
		return pessoa;
	}

	/**
	 * Carrega todos as pessoas encontrados no banco de dados.
	 * @return Lista com as pessoas encontrados.
	 */
	public List<Pessoa> carrega() {
		return session.createCriteria(Pessoa.class).list();
	}

	/**
	 * Recarrega dos dados de pessoa, se neste estiver setado o id.
	 * @param pessoa
	 */
	public void recarrega(Pessoa pessoa) {
		//TODO: fazer essa porra recarregar por cpf e desativar o metodo
		//busca.
		/*
		 * Tentei o codigo abaixo mas não funciona
		Pessoa p;
		if (pessoa.getId() == null) {
		if (pessoa.getCpf() != null || !pessoa.getCpf().equals("")) {
		p = (Pessoa) session.getNamedQuery("Pessoa.findByCpf").setString("cpf", pessoa.getCpf()).uniqueResult();
		for (int i = 0; i <= p.getId(); i++) {
		if (i == p.getId()) {
		pessoa.setId(5);
		break;
		}
		}
		}
		}
		 */

		session.refresh(pessoa);
	}

	public Pessoa busca(String cpf) {
		return (Pessoa) session.getNamedQuery("Pessoa.findByCpf").setString("cpf", cpf).uniqueResult();
	}

	/**
	 * Remove a pessoa do banco de dados deste que nesta esteja setado o id.
	 * @param pessoa Pessoa a ser removida.
	 */
	public void remove(Pessoa pessoa) {
		session.delete(pessoa);
	}

	/**
	 *
	 * @param pessoa
	 * @return verdadeiro se a pessoa for encontrada no banco de dados como aluno.
	 */
	public boolean isAluno(Pessoa pessoa){
		return session.getNamedQuery("Aluno.findByPessoaId")
			.setInteger("pessoaId", pessoa.getId())
			.uniqueResult() != null;
	}

	/**
	 *
	 * @param pessoa
	 * @return verdadeiro se a pessoa for encontrada no banco de dados como administrador.
	 */
	public boolean isAdministrador(Pessoa pessoa){
		return session.getNamedQuery("Administrador.findByPessoaId")
			.setInteger("pessoaId", pessoa.getId())
			.uniqueResult() != null;
	}

	/**
	 *
	 * @param pessoa
	 * @return verdadeiro se a pessoa for encontrada no banco de dados como coordenador.
	 */
	public boolean isCoordenador(Pessoa pessoa){
		return session.getNamedQuery("Coordenador.findByPessoaId")
			.setInteger("pessoaId", pessoa.getId())
			.uniqueResult() != null;
	}
}
